package org.platform.service.diagnose;

import com.mc.mic.core.context.MicLocalContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.platform.constant.DiagnoseConst;
import org.platform.dao.mapper.FdDiagnoseTaskTreeNodeMapper;
import org.platform.dao.mapper.FdDiagnosetaskMapper;
import org.platform.dao.mapper.FdDiagnosetaskTaskMapper;
import org.platform.dao.mapper.FdDiagnosetaskTestMapper;
import org.platform.mo.csmo.cmd21002.TestDiagnoseTaskStopRequestParam;
import org.platform.mo.csmo.cmd21002.TestDiagnoseTaskStopResponseParam;
import org.platform.mo.csmo.cmd41001.AddTaskRequestParam;
import org.platform.mo.csmo.cmd41001.AddTaskResponseParam;
import org.platform.mo.csmo.cmd41002.DelTaskRequestParam;
import org.platform.mo.csmo.cmd41002.DelTaskResponseParam;
import org.platform.mo.csmo.cmd41003.ModifyTaskRequestParam;
import org.platform.mo.csmo.cmd41003.ModifyTaskResponseParam;
import org.platform.mo.csmo.cmd41004.QueryTaskRequestParam;
import org.platform.mo.csmo.cmd41004.QueryTaskResponseParam;
import org.platform.mo.csmo.cmd41016.QueryDiagnoseTaskRequestParam;
import org.platform.mo.csmo.cmd41016.QueryTaskDiagnoseResponseParam;
import org.platform.mo.csmo.common.FD_DiagnoseTask;
import org.platform.mo.csmo.common.FD_TaskDiagnoseTask;
import org.platform.mo.csmo.common.FD_TestDiagnoseTask;
import org.platform.mo.csmo.common.FD_TreeNodeDiagnoseTask;
import org.platform.mo.db.*;
import org.platform.processor.diagnose.DiagnoseTaskProcessor;
import org.platform.processor.knowledge.TreeProcessor;
import org.platform.service.IBaseService;
import org.platform.tool.helper.LogHelper;
import org.platform.tool.util.BeansUtils;
import org.platform.tool.util.ComUtils;
import org.platform.tool.util.SerialNumberUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.util.List;

/**
 * @author FengJie
 * @date 2018/6/8
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class DiagnoseTaskServiceImpl implements IBaseService {
    @Autowired
    private FdDiagnosetaskMapper diagnoseTaskMapper;
    @Autowired
    private FdDiagnosetaskTaskMapper taskMapper;
    @Autowired
    private FdDiagnosetaskTestMapper testMapper;
    @Autowired
    private FdDiagnoseTaskTreeNodeMapper treeNodeMapper;
    @Autowired
    private DiagnoseTaskProcessor taskProcessor;
    @Autowired
    private TreeProcessor treeProcessor;
    @Autowired
    private LogHelper logHelper;

    /**
     * 新建任务（41001）
     *
     * @return
     */
    public AddTaskResponseParam addTask(AddTaskRequestParam requestParam) {
        FdDiagnosetask diagnoseTask = new FdDiagnosetask();
        diagnoseTask.setCreateusername(MicLocalContextHolder.getLocalContext().getUserName());
        BeanUtils.copyProperties(requestParam, diagnoseTask);
        String diagnoseID = "FDS_TP" + SerialNumberUtils.getInstance().getSerialNumber();
        diagnoseTask.setDiagnoseid(diagnoseID);
        diagnoseTask.setStarttime(System.currentTimeMillis());
        diagnoseTask.setEndtime(0L);
        try {
            diagnoseTaskMapper.insertSelective(diagnoseTask);
            switch (diagnoseTask.getType()) {
                case DiagnoseConst.DIAGNOSE_TYPE_TASK_FAULT:
                    FdDiagnosetaskTask task = new FdDiagnosetaskTask();
                    BeanUtils.copyProperties(requestParam.getTaskDiagnoseTask(), task);
                    task.setId(diagnoseID);
                    taskMapper.insert(task);
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_TEST_FAULT:
                    FdDiagnosetaskTest test = new FdDiagnosetaskTest();
                    FD_TestDiagnoseTask testDiagnoseTask = requestParam.getTestDiagnoseTask();
                    BeanUtils.copyProperties(testDiagnoseTask, test);
                    test.setId(diagnoseID);
                    test.setDiagnoseid(diagnoseID);
                    taskProcessor.saveTestParam(test, diagnoseID, testDiagnoseTask.getJsonParam(), test.getTesttype(), testDiagnoseTask.getLoopType());
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_FAULT_TREE:
                    List<FdKbTreenode> fdTreeNodeList = diagnoseTask.getKnowledgeid() != null ?
                            //这里客服端把故障树id通过知识id字段赋值过来的
                            treeProcessor.queryTreeNodeByTreeID(diagnoseTask.getKnowledgeid())
                            //todo 后面再增加设备ID  ->  设备类型
                            : treeProcessor.queryTreeNodeByDevID(diagnoseTask.getDeviceid());
                    fdTreeNodeList.forEach(fdTreeNode -> {
                        //如果叶子节点是诊断类型,就判断知识类型 (0：监测点知识 1：测试知识    2：故障树知识)
                        Integer knowledgeType = fdTreeNode.getNodetype() == DiagnoseConst.FaultTreeNodeTypeEnum.DIAGNOSE.getVal() ?
                                fdTreeNode.getDiagnosetype() : null;

                        FdDiagnoseTaskTreeNode treeNode = new FdDiagnoseTaskTreeNode();
                        BeanUtils.copyProperties(fdTreeNode, treeNode);
                        treeNode.setId(ComUtils.getUUID());
                        treeNode.setTreeid(fdTreeNode.getId());
                        treeNode.setStarttime(diagnoseTask.getStarttime());
                        treeNode.setDiagnoseid(diagnoseID);
                        treeNode.setKnowledgetype(knowledgeType);
                        treeNode.setStatus(DiagnoseConst.DIAGNOSE_STATUS_WAIT);
                        treeNode.setResult(DiagnoseConst.DIAGNOSE_RESULT_NONE);
                        treeNodeMapper.insert(treeNode);
                    });
                    break;
                default:
            }
            String content = "创建" + diagnoseTask.getDiagnosename() + "的诊断任务【成功】";
            logHelper.normal(content, diagnoseID, requestParam.getDeviceid());
        } catch (Exception e) {
            String content = "创建" + diagnoseTask.getDiagnosename() + "的诊断任务【失败】";
            logHelper.error(content, diagnoseID, requestParam.getDeviceid(), e);
        }
        return new AddTaskResponseParam();
    }

    /**
     * 删除任务（41002）
     *
     * @return
     */
    public DelTaskResponseParam delTask(DelTaskRequestParam requestParam) {

        Example example = new Example(FdDiagnosetask.class);
        example.createCriteria()
                .andEqualTo("diagnoseid", requestParam.getDiagnoseid());
        try {
            diagnoseTaskMapper.deleteByExample(example);
            switch (requestParam.getType()) {
                case DiagnoseConst.DIAGNOSE_TYPE_TASK_FAULT:
                    taskMapper.deleteByExample(example);
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_TEST_FAULT:
                    testMapper.deleteByExample(example);
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_FAULT_TREE:
                    treeNodeMapper.deleteByExample(example);
                    break;
                default:
            }
            String content = "删除诊断任务【成功】";
            logHelper.normal(content, requestParam.getDiagnoseid(), null);
        } catch (Exception e) {
            String content = "删除诊断任务【失败】";
            logHelper.error(content, requestParam.getDiagnoseid(), null, e);
        }
        return new DelTaskResponseParam();
    }

    /**
     * 修改任务（41003）
     *
     * @return
     */
    public ModifyTaskResponseParam modifyTask(ModifyTaskRequestParam requestParam) {
        FdDiagnosetask diagnosetask = new FdDiagnosetask();
        BeanUtils.copyProperties(requestParam, diagnosetask);

        try {
            diagnoseTaskMapper.updateByPrimaryKeySelective(diagnosetask);

            Example example = new Example(FdDiagnosetask.class);
            example.createCriteria()
                    .andEqualTo("diagnoseid", requestParam.getDiagnoseid());

            switch (diagnosetask.getType()) {
                case DiagnoseConst.DIAGNOSE_TYPE_TASK_FAULT:
                    FdDiagnosetaskTask task = new FdDiagnosetaskTask();
                    BeanUtils.copyProperties(requestParam.getTaskDiagnoseTask(), task);
                    taskMapper.updateByExampleSelective(task, example);
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_TEST_FAULT:
                    FdDiagnosetaskTest test = new FdDiagnosetaskTest();
                    BeanUtils.copyProperties(requestParam.getTestDiagnoseTask(), test);
                    testMapper.updateByExampleSelective(test, example);
                    break;
                case DiagnoseConst.DIAGNOSE_TYPE_FAULT_TREE:
                    FdDiagnoseTaskTreeNode treeNode = new FdDiagnoseTaskTreeNode();
                    BeanUtils.copyProperties(requestParam.getTreeNodeDiagnoseTask(), treeNode);
                    treeNodeMapper.updateByExampleSelective(treeNode, example);
                    break;
                default:
            }
            String content = "修改诊断任务【成功】";
            logHelper.normal(content, requestParam.getDiagnoseid(), requestParam.getDeviceid());

        } catch (Exception e) {
            String content = "修改诊断任务【失败】";
            logHelper.error(content, requestParam.getDiagnoseid(), requestParam.getDeviceid(), e);
        }
        return new ModifyTaskResponseParam();
    }

    /**
     * 查询任务（41004）
     *
     * @return
     */
    public QueryTaskResponseParam queryTask(QueryTaskRequestParam requestParam) {
        QueryTaskResponseParam responseParam = new QueryTaskResponseParam();
        Example example = new Example(FdDiagnosetask.class);

        if (!requestParam.getDiagnoseid().isEmpty()) {
            example.createCriteria()
                    .andEqualTo("diagnoseid", requestParam.getDiagnoseid());
        }
        List<FdDiagnosetask> diagnoseList = diagnoseTaskMapper.selectByExample(example);
        if (diagnoseList.size() == 1) {
            BeanUtils.copyProperties(diagnoseList.get(0), responseParam);
        }

        List<FdDiagnosetaskTask> taskList = taskMapper.selectByExample(example);
        if (taskList.size() == 1) {
            FD_TaskDiagnoseTask task = new FD_TaskDiagnoseTask();
            BeanUtils.copyProperties(taskList.get(0), task);
            responseParam.setTaskDiagnoseTask(task);
        }

        List<FdDiagnosetaskTest> testList = testMapper.selectByExample(example);
        if (testList.size() == 1) {
            FD_TestDiagnoseTask test = new FD_TestDiagnoseTask();
            BeanUtils.copyProperties(testList.get(0), test);
            responseParam.setTestDiagnoseTask(test);
        }

        List<FdDiagnoseTaskTreeNode> treeNodeList = treeNodeMapper.selectByExample(example);
        if (treeNodeList.size() == 1) {
            FD_TreeNodeDiagnoseTask treeNode = new FD_TreeNodeDiagnoseTask();
            BeanUtils.copyProperties(treeNodeList.get(0), treeNode);
            responseParam.setTreeNodeDiagnoseTask(treeNode);
        }

        return responseParam;
    }

    /**
     * 查询诊断任务集合(41016)
     */
    public QueryTaskDiagnoseResponseParam queryTaskList(QueryDiagnoseTaskRequestParam requestParam) {
        QueryTaskDiagnoseResponseParam responseParam = new QueryTaskDiagnoseResponseParam();
        Example example = new Example(FdDiagnosetask.class);
        Example.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotEmpty(requestParam.getTaskId())) {
            criteria.andEqualTo("taskid", requestParam.getTaskId());
        }
        if (requestParam.getStartTime() != -1) {
            criteria.andGreaterThanOrEqualTo("starttime", requestParam.getStartTime());
        }
        if (requestParam.getEndTime() != -1) {
            criteria.andLessThanOrEqualTo("endtime", requestParam.getEndTime());
        }
        if (requestParam.getType() != -1) {
            criteria.andEqualTo("type", requestParam.getType());
        }
        List<FdDiagnosetask> fdDiagnoseTaskList = diagnoseTaskMapper.selectByExample(example);
        List<FD_DiagnoseTask> diagnoseTaskList = BeansUtils.copyListProperties(fdDiagnoseTaskList, FD_DiagnoseTask.class);
        responseParam.setDiagnoseTaskList(diagnoseTaskList);
        return responseParam;

    }

    /**
     * 中止测试故障诊断任务(21002)
     *
     * @param requestParam
     * @return
     */
    public TestDiagnoseTaskStopResponseParam stopTestDiagnose(TestDiagnoseTaskStopRequestParam requestParam) {
        try {
            taskProcessor.testCancel(requestParam);
            String content = requestParam.getUserID() + "发起终止测试任务,文件发送【成功】";
            logHelper.normal(content, requestParam.getTestPlanID(), null);
        } catch (IOException e) {
            String content = requestParam.getUserID() + "发起终止测试任务,文件发送【失败】";
            logHelper.error(content, requestParam.getTestPlanID(), null, e);
        }
        return new TestDiagnoseTaskStopResponseParam();
    }


}
